﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNA_TD
{
    public class Map : IRunable
    {
        public Dictionary<Vector2, bool> bebaubar;
        public List<Vector2> start;
        public Vector2 end;
        int randomVal, oldLvl = 0;
        Random random;

        public Map()
            : base(Priority.Logic)
        {
            Register(new Terrain());
            map = this;
            bebaubar = new Dictionary<Vector2, bool>();
            random = new Random();
            randomVal = 0;

            start = new List<Vector2>();
            start.Add(new Vector2(94, 21));
            start.Add(new Vector2(57, 3));
            end = new Vector2(26, 30);

            // Linker teil der Map
            for (int x = 26; x <= 31; x++)
            {
                for (int y = 20; y <= 40; y++)
                {
                    if (terrain.istBefahrbar(x, y))
                    {
                        bebaubar.Add(new Vector2(x, y), false);
                    }
                }
            }

            /// Spielfeld
            for (int x = 32; x <= 63; x++)
            {
                for (int y = 20; y <= 40; y++)
                {
                    if (terrain.istBefahrbar(x, y))
                    {
                        bebaubar.Add(new Vector2(x, y), true);
                    }
                }
            }

            /// Rechter teil der Map
            for (int x = 64; x <= 75; x++)
            {
                for (int y = 21; y <= 40; y++)
                {
                    if (terrain.istBefahrbar(x, y))
                    {
                        bebaubar.Add(new Vector2(x, y), false);
                    }
                }
            }

            /// Linie bis zum rechten Start
            for (int x = 76; x <= 95; x++)
            {
                bebaubar.Add(new Vector2(x, 21), false);
            }
            

            /// Rechte Bergseite
            bebaubar.Add(new Vector2(52, 25), false);
            bebaubar.Add(new Vector2(52, 26), false);
            bebaubar.Add(new Vector2(53, 25), false);
            bebaubar.Add(new Vector2(53, 26), false);
            bebaubar.Add(new Vector2(53, 27), false);
            bebaubar.Add(new Vector2(54, 26), false);
            bebaubar.Add(new Vector2(54, 27), false);
            bebaubar.Add(new Vector2(55, 26), false);
            bebaubar.Add(new Vector2(55, 27), false);

            /// Linke Bergseite
            bebaubar.Add(new Vector2(46, 25), false);
            bebaubar.Add(new Vector2(46, 24), false);
            bebaubar.Add(new Vector2(45, 25), false);
            bebaubar.Add(new Vector2(45, 24), false);
            bebaubar.Add(new Vector2(44, 25), false);
            bebaubar.Add(new Vector2(44, 24), false);
            bebaubar.Add(new Vector2(43, 25), false);
            bebaubar.Add(new Vector2(43, 24), false);

            /// von oben nach untern
            bebaubar.Add(new Vector2(57, 3), false);
            bebaubar.Add(new Vector2(57, 4), false);
            bebaubar.Add(new Vector2(57, 5), false);
            bebaubar.Add(new Vector2(57, 6), false);
            bebaubar.Add(new Vector2(56, 7), false);
            bebaubar.Add(new Vector2(57, 7), false);
            bebaubar.Add(new Vector2(56, 8), false);
            bebaubar.Add(new Vector2(57, 8), false);
            bebaubar.Add(new Vector2(55, 9), false);
            bebaubar.Add(new Vector2(56, 9), false);
            bebaubar.Add(new Vector2(55, 10), false);
            bebaubar.Add(new Vector2(56, 10), false);
            bebaubar.Add(new Vector2(54, 11), false);
            bebaubar.Add(new Vector2(55, 11), false);
            bebaubar.Add(new Vector2(53, 12), false);
            bebaubar.Add(new Vector2(54, 12), false);
            bebaubar.Add(new Vector2(55, 12), false);
            bebaubar.Add(new Vector2(53, 13), false);
            bebaubar.Add(new Vector2(54, 13), false);
            bebaubar.Add(new Vector2(52, 14), false);
            bebaubar.Add(new Vector2(53, 14), false);
            bebaubar.Add(new Vector2(51, 15), false);
            bebaubar.Add(new Vector2(52, 15), false);
            bebaubar.Add(new Vector2(53, 15), false);
            bebaubar.Add(new Vector2(54, 15), false);
            bebaubar.Add(new Vector2(55, 15), false);
            bebaubar.Add(new Vector2(50, 16), false);
            bebaubar.Add(new Vector2(51, 16), false);
            bebaubar.Add(new Vector2(52, 16), false);
            bebaubar.Add(new Vector2(53, 16), false);
            bebaubar.Add(new Vector2(54, 16), false);
            bebaubar.Add(new Vector2(49, 17), false);
            bebaubar.Add(new Vector2(50, 17), false);
            bebaubar.Add(new Vector2(51, 17), false);
            bebaubar.Add(new Vector2(52, 17), false);
            bebaubar.Add(new Vector2(53, 17), false);
            bebaubar.Add(new Vector2(54, 17), false);
            bebaubar.Add(new Vector2(48, 18), false);
            bebaubar.Add(new Vector2(49, 18), false);
            bebaubar.Add(new Vector2(50, 18), false);
            bebaubar.Add(new Vector2(51, 18), false);
            bebaubar.Add(new Vector2(52, 18), false);
            bebaubar.Add(new Vector2(53, 18), false);
            bebaubar.Add(new Vector2(54, 18), false);
            bebaubar.Add(new Vector2(47, 19), false);
            bebaubar.Add(new Vector2(48, 19), false);
            bebaubar.Add(new Vector2(49, 19), false);
            bebaubar.Add(new Vector2(50, 19), false);
            bebaubar.Add(new Vector2(51, 19), false);
            bebaubar.Add(new Vector2(52, 19), false);
            bebaubar.Add(new Vector2(53, 19), false);
            bebaubar.Add(new Vector2(54, 19), false);
            pfad = new Pfad();
        }

        public bool istBefahrbahr(Vector2 pos)
        {
            if (!bebaubar.ContainsKey(pos))
                return false;
            if (bebaubar[pos])
                return true;
            return !gameManager.durchTurmGeblockt(pos);
        }

        public Vector3 getStart(int lvl, float hoehe)
        {
            if (oldLvl != lvl)
            {
                randomVal = random.Next(3);
                oldLvl = lvl;
            }
            var s = start[randomVal % start.Count];
            return new Vector3(s.X, hoehe, s.Y);
        }

        public Vector3 getAirStart(float hoehe)
        {
            var s = start[0];
            return new Vector3(s.X, hoehe, s.Y - 10 + random.Next(21));
        }

        public bool istBebaubar(Vector2 pos)
        {
            if (!bebaubar.ContainsKey(pos))
                return false;
            if (!bebaubar[pos])
                return false;

            bebaubar.Remove(pos);
            var neuerPfad = new Pfad();
            bebaubar.Add(pos, true);
            foreach (var s in start)
            {
                if (!neuerPfad.hasNext(s))
                    return false;
            }
            return true;
        }

        public bool istBebaubarOhneTestDesPfades(Vector2 pos)
        {
            if (!bebaubar.ContainsKey(pos))
                return false;
            if (!bebaubar[pos])
                return false;
            return true;
        }

        public override void Load()
        {
        }

        public override void UnLoad()
        {
        }

        public void Bauen(Vector3 position)
        {
            bebaubar[new Vector2(position.X, position.Z)] = false;
            pfad.Recalculate();
        }

        public void Entfernen(Vector3 position)
        {
            bebaubar[new Vector2(position.X, position.Z)] = true;
            pfad.Recalculate();
        }
    }
}
